/*************************************************************
 *Name:           Christopher Alexander
 *Email address:  alexanc2@onid.oregonstate.edu
 *Class name:     CS362
 *Assignment:     Assignment #3
 *Description:    This file (cardtest2.c) contains random tests
                  for the village card in dominion.c
 *************************************************************/

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include "rngs.h"

#define NUM_UNIQUE_CARDS 27 //At least by my count this is right.
#define NUM_TESTS 5000

void fillWithCards(struct gameState *testState, int count, int flag, int *k, int player){

   int i;
   int randTreasure;
   int randKingdom;

   //Fill hand with random cards:
   if (flag == 0){
      for (i = 0; i < testState->handCount[player]; i++){
         if ( (rand() % 4) == 0){ //Add a treasure card 25% of the time.
            randTreasure = (rand() % 3); //33% of the time each for copper, silver, gold.
            if (randTreasure == 0) testState->hand[player][i] = copper;
            else if (randTreasure == 1) testState->hand[player][i] = silver;
            else testState->hand[player][i] = gold;
         }
         else { //Randomly fill with kingdom card 75% of the time.
            randKingdom = (rand() % 10); //There are 10 kingdom cards. Choose one randomly.
            if (randKingdom == 0) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 1) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 2) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 3) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 4) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 5) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 6) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 7) testState->hand[player][i] = k[randKingdom];
            else if (randKingdom == 8) testState->hand[player][i] = k[randKingdom];
            else testState->hand[player][i] = k[randKingdom];
         }
      } //End fill hand with random cards.
   }
   else if (flag == 1){
      //Fill deck with random cards:
      for (i = 0; i < testState->deckCount[player]; i++){
          if ( (rand() % 4) == 0){ //Add a treasure card 25% of the time.
            randTreasure = (rand() % 3); //33% of the time each for copper, silver, gold.
            if (randTreasure == 0) testState->deck[player][i] = copper;
            else if (randTreasure == 1) testState->deck[player][i] = silver;
            else testState->deck[player][i] = gold;
         }
         else { //Randomly fill with kingdom card 75% of the time.
            randKingdom = (rand() % 10); //There are 10 kingdom cards. Choose one randomly.
            if (randKingdom == 0) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 1) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 2) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 3) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 4) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 5) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 6) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 7) testState->deck[player][i] = k[randKingdom];
            else if (randKingdom == 8) testState->deck[player][i] = k[randKingdom];
            else testState->deck[player][i] = k[randKingdom];
         }
      } //End fill deck with random cards.
   }
   else {
      //Fill discard with random cards:
      for (i = 0; i < testState->discardCount[player]; i++){
          if ( (rand() % 4) == 0){ //Add a treasure card 25% of the time.
            randTreasure = (rand() % 3); //33% of the time each for copper, silver, gold.
            if (randTreasure == 0) testState->discard[player][i] = copper;
            else if (randTreasure == 1) testState->discard[player][i] = silver;
            else testState->discard[player][i] = gold;
         }
         else { //Randomly fill with kingdom card 75% of the time.
            randKingdom = (rand() % 10); //There are 10 kingdom cards. Choose one randomly.
            if (randKingdom == 0) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 1) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 2) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 3) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 4) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 5) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 6) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 7) testState->discard[player][i] = k[randKingdom];
            else if (randKingdom == 8) testState->discard[player][i] = k[randKingdom];
            else testState->discard[player][i] = k[randKingdom];
         }
      } //End fill discard with random cards.
   }
}


int main() {
   int n;
   int seed = 1000;
   int numPlayers;
   int player;
   int bonus = 0;
   int choice1 = 0;
   int choice2 = 0;
   int choice3 = 0;
   int handPos = 0;
   int returnValue;
   int hadToShuffle = 0;
   int anyInDiscard = 1;
   int countOfHand;
   int k[10] = {adventurer, council_room, feast, gardens, mine,
               remodel, smithy, village, baron, great_hall};
   struct gameState testState;
   struct gameState preState;

   srand(time(NULL));
   printf("\nTesting village card in cardEffect():\n");

   for (n = 0; n < NUM_TESTS; n++) {

      numPlayers = (rand() % 3) + 2; //There can be 2-4 players.

      initializeGame(numPlayers, k, seed, &testState); // initialize a new game

      player = rand() % numPlayers; //Randomly choose player to test.
      testState.whoseTurn = player;  //Make it this player's turn.

      testState.handCount[player] = (rand() % 10) + 1; //Player's hand size at start of turn. Have at least 1 card.
      testState.deckCount[player] = (rand() % 20); //How many cards are in player's deck
      testState.discardCount[player] = (rand() % 20); //How many cards are in player's discard pile.

      fillWithCards(&testState, testState.handCount[player], 0, k, player);
      fillWithCards(&testState, testState.deckCount[player], 1, k, player);
      fillWithCards(&testState, testState.discardCount[player], 2, k, player);

      handPos = rand() % testState.handCount[player]; //Card to play can be in any location in player's hand.
      testState.hand[player][handPos] = village; //Make sure player has village in hand at handPos position.

      memcpy(&preState, &testState, sizeof(struct gameState));

      //Testing village card.
      returnValue = cardEffect(testState.hand[player][handPos], choice1, choice2, choice3, &testState, handPos, &bonus);

      //Manually recreate what village card does.

      //Did the deck need shuffling?
      if (preState.deckCount[player] == 0){
         hadToShuffle = 1;
      }
      if (preState.discardCount[player] == 0){
         anyInDiscard = 0;
      }
      countOfHand = preState.handCount[player];

      drawCard(player, &preState);
      preState.numActions = preState.numActions + 2;
      discardCard(handPos, player, &preState, 0);

      //Testing what cardEffect did.
      if (hadToShuffle == 0){
         if (memcmp(&preState, &testState, sizeof(struct gameState)) != 0){
            printf("\tBUG FOUND TESTING village in cardEffect()\n");
         }
      }
      else { //Had to shuffle discards.

         if (anyInDiscard != 0){ // If there were card(s) to move to the deck.
            if (preState.numActions != testState.numActions){
               printf("\tBUG FOUND TESTING village\n\t"
                     "numActions not incremented by 2 when shuffling was needed.\n");
            }
            if (testState.discardCount[player] != preState.discardCount[player]){
               printf("\tBUG FOUND TESTING village\n\t"
                     "discardCount not correct when shuffling was needed.\n");
            }
         }
         //If there were no cards to draw, player will not receive a card, but will
         //discard village, resulting in handCount being 1 less than it started at.
         else {
            if (testState.handCount[player] != (countOfHand - 1)){
               printf("\tBUG FOUND TESTING village\n\t"
                     "Handcount should be one less when no cards in deck and discard piles.\n");
            }
         }

      } //End Testing what cardEffect did.

      hadToShuffle = 0; //Reset for next test.
      anyInDiscard = 1; //Reset for next test.
   }

   return 0;
}
